'''
1、环境搭建说明：test_sdk_api放在/data路径

 需要设置项：设置模块的DEBUG口

2、脚本运行逻辑：
  1.循环对所有功能接口进行初始化去初始化压力测试
  2.设置QSSRM等级设置AT+QMSSR=3,执行AT+qtest=-"dump",1触发一次dump，触发MODEM重启
3、版本RN：
 v2.0：再次编写
'''

import serial
import time
import os
import sys
import random
import re

DEBUG_PORT = "COM4"
BAUDRATE = 115200
AT_PORT = 'COM9'  # 根据实际情况修改端口号
#AT指令和返回值检查
# 定义变量
debug_serial = None

#记录运行次数
runTimes		= 0

#log文件
DEBUG_LOG		  = ""

# 创建日志文件
def creatLogFile():
 global DEBUG_LOG

 DEBUG_LOG = "DEBUG_LOG_{}.log".format(time.strftime("%Y-%m-%d_%H_%M_%S", time.localtime()))

#log写入函数
def write_log(log,logFile=""):
 with open(logFile, 'a') as file_object:
  file_object.write(str(time.strftime("%Y-%m-%d %H:%M:%S", time.localtime())) + "\r\n" + log+ "\r\n")
  print(log)

#发送at指令
def at_write(command, timeout, DEBUG_PORT_opened, at_result,RDY=0,CPIN=0):
 write_log(str(time.strftime("%Y-%m-%d %H:%M:%S", time.localtime())),DEBUG_LOG)
 at_command = command.encode("UTF-8")
 DEBUG_PORT_opened.write(at_command)

#读取at口返回
def at_read(serial_port, logFile=""):
 rec_str = ''
 while (True):
  time.sleep(1)
  lenth = serial_port.inWaiting()
  if lenth > 0:
   rec_str = serial_port.read(size=lenth)
   try:
    rec_str = re.sub('\\x1b.*?m', "", rec_str.decode("UTF-8"), 0, re.I)
    if logFile != "":
     with open(logFile, 'a') as file_object:
      rec_str = str(time.time()) + ":" + str(
       time.strftime("%Y-%m-%d %H:%M:%S", time.localtime())) + "\r\n" + rec_str
      file_object.write(
       str(time.strftime("%Y-%m-%d %H:%M:%S", time.localtime())) + "\r\n" + rec_str + "\r\n")
    return rec_str
   except:
    return ""
  else:
   break
 return rec_str

# 登录设备
def loginDevice():
 global DEBUG_LOG
 #确认登录失败的条件，或者，不可能失败
 while True:
  print("等待登录... ... ")
  time.sleep(3)
  at_write("\r\n",3,debug_serial,"OK")
  result = at_read(debug_serial)

  with open(DEBUG_LOG, 'a') as file_object:
   file_object.write(result)

  if "login:" in result:
   at_write("root\r\n",3,debug_serial,"OK")
   print("账号输入成功")
   time.sleep(2)
   at_write("oelinux123\r\n",3,debug_serial,"OK")
   print("密码输入成功")
  elif "~ #" in result:
   print("登录成功")
   at_write("echo 2 >/proc/sys/kernel/printk\r\n",3,debug_serial,"OK")
   break
  else:
   continue 

#检查debug口通信状态
def check_port_status():
 global debug_serial
 if debug_serial == None:
  try:
   debug_serial = serial.Serial(DEBUG_PORT,BAUDRATE)
  except:
   print("at口连接失败，请检查端口")
   sys.exit()

# 写入运行次数到日志
def writeRuntimesToLog():
 global runTimes
 with open(DEBUG_LOG, 'a+') as file_object:
  file_object.write("\r\n{} runtimes: {} {}\r\n".format("<"*20,runTimes,">"*20))
 print("\r\n{} runtimes: {} {}\r\n".format("<"*20,runTimes,">"*20))
 runTimes += 1

# 进入测试接口
def intoTestInterface_testsdk(debug_serial,logFile):
 at_write("cd /data\r\n./test_sdk_api\r\n",3,debug_serial,"OK")
 result = at_read(debug_serial,logFile)

# 退出测试接口
def exit_testsdk(debug_serial,logFile):
 at_write("-1\n-1\n",3,debug_serial,"OK")
 result = at_read(debug_serial,logFile)

# 返回测试接口
def back_testsdk(debug_serial,logFile):
 at_write("-1\n",3,debug_serial,"OK")
 result = at_read(debug_serial,logFile)

# 断言检查
def ASSERT(debug_serial):
 result = at_read(debug_serial,DEBUG_LOG)
 if ("Fail" in result) or (" error" in result):
  print("init失败,等待退出")
  time.sleep(10)
  at_write("killall logcat\n",3,debug_serial,"OK")
  sys.exit()
 elif ("init ok" in result) or ("Success" in result):
  print("init成功")

#关键字检测
def find_keywords_with_ids(debug_serial, keywords=["_init", "deinit"]):
    logs = at_read(debug_serial, "DEBUG_LOG")
    log_lines = logs.split('\n')
    keyword_ids = {keyword: [] for keyword in keywords}
    for line in log_lines:
        parts = line.split('\t', 1)
        if len(parts) < 2:
            continue
        log_id, log_content = parts
        
        for keyword in keywords:
            if keyword in log_content:
                keyword_ids[keyword].append(log_id)
    
    return keyword_ids

#字符串注入
def inject_ids_into_string(template, ids):
    for keyword, id_list in ids.items():
        for i, log_id in enumerate(id_list):
            placeholder = f"{keyword}_{i}"
            template = template.replace(placeholder, log_id)
    return template
#modem重启
def reboot_modem():
    try:
        # 打开串口
        ser = serial.Serial(AT_PORT, BAUDRATE)
        
      # 发送 AT+QMSSR? 指令
        ser.write(b'AT+QMSSR?\r\n')
        time.sleep(0.5)
        response_qmssr = ser.read_all().decode()
        
        # 检查 QMSSR 返回值是否为 3
        if "OK" in response_qmssr and '3' in response_qmssr:
            print("QMSSR 等级已为 3")
        else:
            # 如果 QMSSR 返回值不是 3，设置为 3
            print("QMSSR 等级不是 3")
            ser.write(b'AT+QMSSR=3\r\n')
            time.sleep(0.5)
            response_set_qmssr = ser.read_all().decode()
            if "OK" in response_set_qmssr:
                print("QMSSR 等级设置为 3 成功")
            else:
                print("设置 QMSSR 等级为 3 失败")
                ser.close()
                return False
        # 发送 AT+qtest="dump",1 指令
        ser.write(b'AT+qtest="dump",1\r\n')
        time.sleep(5)
        response_dump = ser.read_all().decode()
        
        # 检查重启成功的返回值
        if "RDY" in response_dump:
            print("指令执行成功，modem 重启成功")
            ser.close()
            return True
        else:
            print("返回值不是 'RDY'")
            ser.close()
            return False
    except Exception as e:
        print(f"发生错误: {e}")
        return None

# SDK初始化和去初始化
def sdk_init_deinit():
    intoTestInterface_testsdk(debug_serial,DEBUG_LOG)
    for i in range(14):
        at_write("{}\n".format(str(i)),3,debug_serial,"OK")
        time.sleep(1)
        ids =find_keywords_with_ids(debug_serial)
        templates ="\n_init_0\ndeinit_0\n-1\n"
        debug_result = inject_ids_into_string(templates, ids)
        at_write(debug_result,3,debug_serial,"OK")
        print(f"第{i+1}次初始化功能对应的编号: {i}")
        ASSERT(debug_serial)
        time.sleep(1)
    exit_testsdk(debug_serial,DEBUG_LOG)

# 检查CPU占用率
def check_cpuoccupy():
 at_write("^C\n",3,debug_serial,"OK")
 at_write("top -n 1 |grep idle\n",3,debug_serial,"OK")
 result = at_read(debug_serial,DEBUG_LOG)
 print
 cpu_idle = result.split("nic ")[1].split("% idle")[0]
 print(f"cpu占用率为{cpu_idle}")
 if float(cpu_idle) < 10:
  print("cpu占用超过90%")
  sys.exit()

if __name__ == "__main__":

#连接端口
 check_port_status()
 creatLogFile()
 loginDevice()
 time.sleep(2)
 time.sleep(5)
while True:
  writeRuntimesToLog()
  time.sleep(2)
  #循环测试
  sdk_init_deinit()
  time.sleep(2)
  check_cpuoccupy()
  time.sleep(5)
  reboot_modem()
  time.sleep(5)
  
  
  
  